//-----------------------------------------------------------------------
// <copyright file="CreateVirtualDirectory.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <summary>Creates a new Virtual Directory.</summary>
//-----------------------------------------------------------------------
namespace Microsoft.Sdc.Tasks.Web.WebSite
{
    using System;
    using Microsoft.Sdc.Tasks.Configuration.Web;
    using Microsoft.Build.Framework;

    /// <summary>
    /// Create a new virtual directory
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[<Web.WebSite.CreateVirtualDriectory
    ///     VirtualDirectoryName="virtualDirectoryName" 
    ///     Path="path" 
    ///     MachineName="machineName"
    ///     AppPoolID="appPoolID" 
    ///     AppCreate="appCreate" 
    ///     WebSiteName="webSiteName"
    ///     AnonymousUserName="anonymousUserName"
    ///     AnonymousUserPassword="anonymousUserPassword"
    ///     UncUserName="uncUserName"
    ///        UncPassword="uncPassword"
    ///     AuthFlags="authenticationFlags"
    ///     AccessFlags="accessFlags"
    /// />]]></code>
    /// <para>where:</para>
    /// <para><i>virtualDirectoryName (Required)</i></para>
    /// <para>name of the virtual driectory to create</para>
    /// <para><i>path (Required)</i></para>
    /// <para>Path to map the virtual directory to.</para>
    /// <para><i>machineName</i></para>
    /// <para>Machine to add the virtual directory on.</para>
    /// <para><i>appPoolID</i></para>
    /// <para>Application pool to run the virtual directory under (IIS6 only).</para>
    /// <para><i>appCreate</i></para>
    /// <para>Set to "true" to create an application for this virtual directory.</para>
    /// <para><i>webSiteName</i></para>
    /// <para>Web site to attach the virtual directory onto.</para>
    /// <para><i>anonymousUserName</i></para>
    /// <para>Account to run anonymous users under.</para>
    /// <para><i>anonymousUserPassword</i></para>
    /// <para>Password for the anonymous users account.</para>
    /// <para><i>uncUserName</i></para>
    /// <para>Account to connect to a UNC share under when the Path property is a UNC path.</para>
    /// <para><i>uncPassword</i></para>
    /// <para>Password for the connection to a UNC share.</para>
    /// <para><i>authFlags</i></para>
    /// <para>Authentication flags to apply to the directory.</para>    
    /// <para><i>accessFlags</i></para>
    /// <para>Access flags to apply to the directory.</para>    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <Web.WebSite.CreateVirtualDirectory
    ///                 VirtualDirectoryName="vdirName" 
    ///                 Path="c:\temp" 
    ///                 MachineName="remotemachine"
    ///                 AppPoolID="IIS6AppPool" 
    ///                 AppCreate="1|0" 
    ///                 WebSiteName="MySite"
    ///                 AnonymousUserName="anonaccount"
    ///                 AnonymousUserPassword="anonpassword"
    ///                 UncUserName="domain\user"
    ///                    UncPassword="uncpassword"
    ///                 AuthFlags="authenticationFlags" />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>    
    public class CreateVirtualDirectory : TaskBase
    {
        private string machineName = "localhost";
        private string webSiteName = "Default Web Site";
        private string webAppName = String.Empty;
        private string name = String.Empty;
        private string appPoolId = "DefaultAppPool";
        private string authFlagsFromConfig = String.Empty;
        private string accessFlagsFromConfig = String.Empty;
        private string anonymousUserName = String.Empty;
        private string anonymousUserPassword = String.Empty;
        private string uncUserName = String.Empty;
        private string uncPassword = String.Empty;
        private string path = String.Empty;
        private bool appCreate = true;

        /// <summary>
        /// Name of the virtual driectory to be created
        /// </summary>
        /// <value>any valid directory name</value>
        [Required]
        public string VirtualDirectoryName
        {
            get { return (this.name ?? String.Empty); }
            set { this.name = value; }
        }

        /// <summary>
        /// Root path for the virtual directory
        /// </summary>
        /// <value>Existing directory path</value>
        [Required]
        public string Path
        {
            get { return (this.path ?? String.Empty); }
            set { this.path = value; }
        }

        /// <summary>
        /// Name of the machine to create the new virtual directory on
        /// </summary>
        /// <value>A valid machine name</value>
        public string MachineName
        {
            get { return (this.machineName ?? String.Empty); }
            set { this.machineName = value; }
        }

        /// <summary>
        /// Site name to create new virtual directory on
        /// </summary>
        /// <value>A valid site name</value>
        /// <remarks>If this is not specified the virtual directory will be created 
        /// on "Default Web Site"</remarks>
        public string WebSiteName
        {
            get { return (this.webSiteName ?? String.Empty); }
            set { this.webSiteName = value; }
        }

        /// <summary>
        /// The name of the Web Application to create
        /// <value>A valid Web Application name</value>
        /// <remarks>If this is not supplied or empty, the folder will remain a virtual directory</remarks>
        /// </summary>
        public string WebAppName
        {
            get { return this.webAppName; }
            set { this.webAppName = value; }
        }

        /// <summary>
        /// Application Pool ID to run virtual directory under
        /// </summary>
        /// <value>A valid application pool ID</value>
        public string AppPoolId
        {
            get { return (this.appPoolId ?? String.Empty); }
            set { this.appPoolId = value; }
        }

        /// <summary>
        /// Create a specific application for this virtual director
        /// </summary>
        /// <value>True or False</value>
        public bool AppCreate
        {
            get { return this.appCreate; }
            set { this.appCreate = value; }
        }

        /// <summary>
        /// Account to run anonymous users under in this directory
        /// </summary>
        /// <value>A valid user account</value>
        public string AnonymousUserName
        {
            get { return (this.anonymousUserName ?? String.Empty); }
            set { this.anonymousUserName = value; }
        }

        /// <summary>
        /// Password for the anonymous user process
        /// </summary>
        /// <value>A valid password for the specified user name</value>
        public string AnonymousUserPassword
        {
            get { return (this.anonymousUserPassword ?? String.Empty); }
            set { this.anonymousUserPassword = value; }
        }

        /// <summary>
        /// Account to connect to a UNC share under when the Path property contains a UNC share
        /// </summary>
        /// <value>A valid user account</value>
        public string UncUserName
        {
            get { return (this.uncUserName ?? String.Empty); }
            set { this.uncUserName = value; }
        }

        /// <summary>
        /// Password for the user used to connect to a UNC share
        /// </summary>
        /// <value>A valid password for the specified UncUserName</value>
        public string UncPassword
        {
            get { return (this.uncPassword ?? String.Empty); }
            set { this.uncPassword = value; }
        }

        /// <summary>
        /// Authentication methods for the site
        /// </summary>
        /// <value>A combination of </value>
        /// <value>NTLM </value>
        /// <value>Anonymous </value>
        /// <value>Basic </value>
        /// <value>Digest</value>
        /// <remarks>If unspecified the site will default to anonymous and NTLM</remarks>
        public string AuthFlags
        {
            get { return (this.authFlagsFromConfig ?? String.Empty); }
            set { this.authFlagsFromConfig = value; }
        }

        /// <summary>
        /// Access methods for the directory
        /// </summary>
        /// <value>  AccessNoAccess</value> 
        /// <value>  AccessRead</value>
        /// <value>  AccessWrite</value>
        /// <value>  AccessExecute</value>
        /// <value>  AccessSource</value>
        /// <value>  AccessScript</value>
        /// <value>  AccessNoRemoteWrite</value>
        /// <value>  AccessNoRemoteRead</value>
        /// <value>  AccessNoRemoteExecute</value>
        /// <value>  AccessNoRemoteScript</value>
        /// <remarks>If unspecified the site will default to scripts and executables</remarks>
        public string AccessFlags
        {
            get { return (this.accessFlagsFromConfig ?? String.Empty); }
            set { this.accessFlagsFromConfig = value; }
        }

        /// <summary>
        /// Performs the action of this task.
        /// </summary>
        protected override void InternalExecute()
        {
            AuthFlags authFlags = 0;
            AccessFlags accessFlags = 0;

            WebSite web;
            VirtualDirectory vdir;

            if (this.authFlagsFromConfig.Length == 0)
            {
                authFlags = Microsoft.Sdc.Tasks.Configuration.Web.AuthFlags.Anonymous | Microsoft.Sdc.Tasks.Configuration.Web.AuthFlags.NTLM;
            }
            else
            {
                string[] authFlagsSplit = this.authFlagsFromConfig.Split(' ');
                foreach (string authFlagsSplitItem in authFlagsSplit)
                {
                    object flags = Enum.Parse(typeof(AuthFlags), authFlagsSplitItem, true);
                    authFlags = authFlags | (AuthFlags) flags;
                }
            }

            if (this.accessFlagsFromConfig.Length == 0)
            {
                accessFlags = Microsoft.Sdc.Tasks.Configuration.Web.AccessFlags.AccessRead | Microsoft.Sdc.Tasks.Configuration.Web.AccessFlags.AccessScript | Microsoft.Sdc.Tasks.Configuration.Web.AccessFlags.AccessExecute;
            }
            else
            {
                string[] accessFlagsSplit = this.accessFlagsFromConfig.Split(' ');
                foreach (string accessFlagsSplitItem in accessFlagsSplit)
                {
                    object flags = Enum.Parse(typeof(AccessFlags), accessFlagsSplitItem, true);
                    accessFlags = accessFlags | (AccessFlags) flags;
                }
            }

            web = WebSite.Load(this.machineName, this.webSiteName);

            // if it exists do nothing
            if (web.VirtualDirectories[this.name] == null)
            {
                Log.LogMessageFromResources("Web.CreateVirtualDirectory", this.name);
                vdir = new VirtualDirectory(this.name, this.webAppName);

                // TODO read these from xml or default
                vdir.AppPoolId = this.appPoolId;
                vdir.AuthFlags = authFlags;
                vdir.AccessFlags = accessFlags;

                if (string.IsNullOrEmpty(this.anonymousUserName) == false)
                {
                    vdir.AnonymousUserName = this.anonymousUserName;
                    vdir.AnonymousUserPassword = this.anonymousUserPassword;
                }

                if (string.IsNullOrEmpty(this.uncUserName) == false)
                {
                    vdir.UncUserName = this.uncUserName;
                    vdir.UncPassword = this.uncPassword;
                }

                vdir.Path = System.IO.Path.GetFullPath(this.path);
                web.VirtualDirectories.Add(vdir);
                web.Save();
                if (this.appCreate)
                {
                    vdir.AppCreate3();
                }
                else
                {
                    try
                    {
                        vdir.AppDelete();
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            else
            {
                Log.LogMessageFromResources(MessageImportance.Low, "Web.VirtualDirectoryExists", this.name);
            }
        }
    }
}